package com.cc.service;

import com.cc.annotation.MeSelfAutowired;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.context.annotation.*;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.event.EventListener;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

/**
 * @title: UserService
 * @author: lbj
 * @date: 2022/5/5 6:09 下午
 * @description: TODO 类描述
 */

//@MeCom //自定义 bean 扫描注解
//@Conditional(value = {MeConditional.class})
//@Component
//@Lazy
//@ComponentScan("com.cc")

//@Component
public class UserService {
//public class UserService implements InitializingBean,DisposableBean{
//public abstract class UserService {
//public class UserService implements ImportBeanDefinitionRegistrar {

//    @PostConstruct
//    public void init(){
//        System.out.println("init");
//    }
//
//    @PreDestroy
//    public void detory(){
//        System.out.println("detory");
//    }
//
//    @Override
//    public void destroy() throws Exception {
//        System.out.println("DisposableBean");
//    }
//
//    @Override
//    public void afterPropertiesSet() throws Exception {
//        System.out.println("afterPropertiesSet");
//    }

//    @PostConstruct
//    @PreDestroy
//    public void init(){
//
//    }
//
//    @Override
//    public void afterPropertiesSet() throws Exception {
//
//    }
//
//    @Override
//    public void destroy() throws Exception {
//
//    }
//
//    @Override
//    public void setBeanClassLoader(ClassLoader classLoader) {
//
//    }
//
//    @Override
//    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
//
//    }
//
//    @Override
//    public void setBeanName(String name) {
//
//    }

//    @MeSelfAutowired
//    @Autowired
//    private OrderService orderService;
//
//    @Autowired
//    private ApplicationContext applicationContext;

//    @Autowired
//    private ApplicationEventMulticaster applicationEventMulticaster;
//
//    public void test(){
//        applicationEventMulticaster.multicastEvent(new PayloadApplicationEvent<String>(this,"user send event"));
//    }
//
//    public void test2(){
//        System.out.println("tesadfdfdt....");
//    }
//
//    @EventListener
//    public void listenerTest(ApplicationEvent event){
//        if (event instanceof PayloadApplicationEvent) {
//            PayloadApplicationEvent e = (PayloadApplicationEvent) event;
//            System.out.println(e.getPayload());
//        }
//    }





    //    @Autowired // 加载 set方法上使用
//    public void setOrderService(OrderService orderService) {
//        this.orderService = orderService;
//    }

//    @Lazy
//    @Autowired //加在属性上使用

    /**
     * @Resource
     * 先根据名称查找对应的 bean ,存在即返回
     * 不存在，再按类型查找，单个类型直接返回，多个类型直接抛错
     * @Resource(name = "orderService2")
     * 可指定 bean 直接注入，不存在则抛错
     */
//    @Resource(name = "orderService2")
//    private OrderService orderService221;

//    @Async
//    @Lookup
//    public OrderService test(){
//        System.out.println("abdff");
//        return null;
//    }

//    @Override
//    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
//
//        final BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition();
//        final AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
//        beanDefinition.setBeanClass(OrderService.class);
//
//        registry.registerBeanDefinition("orderService",beanDefinition);
//    }

    //    @Override
//    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//        return new String[]{OrderService.class.getName()};
//    }

    //默认使用无参构造方法
//    public UserService() {
//        System.out.println(0);
//    }

    //仅有一个构造方法时，会用唯一的构造方法
//    public UserService(OrderService orderService) {
//        this.orderService = orderService;
//        System.out.println(1);
//    }

//    @Autowired  // 多个构造方法时，优先使用 @Autowired 注解的方法
//    public UserService(OrderService orderService,OrderService orderService1) {
//        this.orderService = orderService;
//        System.out.println(2);
//    }


//    @Value("${lbj}")  // 注入配置
//    @Value("lbj")       // 注入字符串
//    private String test;

//    @Value("#{orderService}") //sp-el 注入 bean
//    private OrderService orderService;

//    @LocalServerPort  //通用注解
//    private String port;


    /**
     * @Autowired
     * byType 注入，只有一个类型实现，直接注入
     * 找到多个类，再按名字匹配，没有符合名字，抛异常
     * @see org.springframework.beans.factory.UnsatisfiedDependencyException
     *
     * @Autowired(required = false)
     * 可取消强制注入，不存在不注入
     *
     * @Qualifier("orderService1")
     * @Autowired
     * 组合使用，指定名称注入 bean
     *
     */
//    @Qualifier("orderService1")
//    @Autowired
////    @Autowired(required = false)
//    private OrderService ddfdf;
//
//    public void test(){
//        System.out.println(ddfdf);
//    }

//    public void setOrderService(OrderService orderService) {
//        this.orderService = orderService;
//        System.out.println("setOrderService");
//    }


//    @Bean
//    public OrderService orderService() {
//        return new OrderService();
//    }



}
